package cn.youframe.frame.exception;

/**
 * User: Administrator
 * DateTime: 12-7-22 下午1:29
 * Desc:
 */
public class YfRuntimeException extends RuntimeException {
    /**
     * 加工后的错误提示信息
     */
    protected String errorMessage;

    protected String errorCode;

    private Object[] messageArgs;

    // 注意：errorCode + messageArgs与message(构造函数的入参)的区别：
    // 1、errorCode + messageArgs是为了提示给用户的信息，而用户界面就会考虑国际化。errorCode对应错误提示的串信息，
    // messageArgs是对应串的补充信息，例如：“USER_ID违反UK_T_USER_ID约束”（表示UserId列违反了唯一约束），此错误
    // 提示将被分解为：1001 =
    // {0}违反{1}约束，那么：errorCode值为1001，messageArgs={"USER_ID","UK_T_USER_ID"}；
    // 2、构造函数的message入参，此提示是用于记录日志，供分析错误用，不会直接提示给业务人员。

    /**
     * 不带参数的构造子
     */
    public YfRuntimeException() {
        super();
    }

    /**
     * @param errorCode 错误代码，此错误代码将对应一条可国际化的异常描述，此类似与Oracle等的错误代码
     * @param messageArgs 异常描述的参数，用于错误描述中仅有一个参数的情况
     */
    public YfRuntimeException(String errorCode, Object... messageArgs) {
        super();
        initErrorMessage(errorCode, messageArgs);
    }

    /**
     * @param logMessage 记录日志的消息
     */
    public YfRuntimeException(String logMessage) {
        super(logMessage);
        setDefaultErrorCode();
    }

    /**
     * @param logMessage 记录日志的消息
     * @param errorCode 错误代码，此错误代码将对应一条可国际化的异常描述，此类似与Oracle等的错误代码
     * @param messageArgs 异常描述的参数，用于错误描述中仅有一个参数的情况
     */
    public YfRuntimeException(String logMessage, String errorCode,Object... messageArgs) {
        super(logMessage);
        initErrorMessage(errorCode, messageArgs);
    }

    /**
     * @param cause 引起异常的原始异常
     */
    public YfRuntimeException(Throwable cause) {
        super(cause);
        setDefaultErrorCode();
    }

    /**
     * @param cause 引起异常的原始异常
     * @param logMessage 记录日志的消息
     */
    public YfRuntimeException(Throwable cause, String logMessage) {
        super(logMessage, cause);
        setDefaultErrorCode();
    }

    /**
     * @param logMessage 记录日志的消息
     * @param errorCode 错误代码，此错误代码将对应一条可国际化的异常描述，此类似与Oracle等的错误代码
     * @param cause 引起异常的原始异常
     */
    public YfRuntimeException(Throwable cause, String logMessage,
                              String errorCode, Object... messageArg) {
        super(logMessage, cause);
        initErrorMessage(errorCode,messageArg);
    }

    /**
     * 设置错误消息的错误代码，用于在构造函数中没有设置errorCode和messageArg的情况。如果在构造函数中设置的errorCode和messageArg，那么此设置将覆盖原设置。
     *
     * @param errorCode 错误代码，此错误代码将对应一条可国际化的异常描述，此类似与Oracle等的错误代码
     * @param messageArgs 异常的参数，可以没有也可以一个或多个。
     */
    public void initErrorMessage(String errorCode, Object... messageArgs) {
        this.errorCode = errorCode;
        this.messageArgs = messageArgs;
    }

    /**
     * 设置默认的ErrorCode
     */
    protected void setDefaultErrorCode() {
        this.errorCode = "ERR-000";
    }

    /**
     * 得到具体的错误消息
     */
    public String getErrorMessage() {
        if (errorMessage == null) {
            if (errorCode != null) {
                StringBuffer sb = new StringBuffer(errorCode).append(":");
                errorMessage = sb.toString();
            } else {
                errorMessage = this.getMessage();// 如果未定义ErrorCode，那么直接将未国际化的日志信息作为提示信息。
            }
        }
        return errorMessage;
    }

    /**
     * @return the errorCode
     */
    public String getErrorCode() {
        return this.errorCode;
    }

    /**
     * @return the messageArgs
     */
    public Object[] getMessageArgs() {
        return this.messageArgs;
    }
}
